/*
setTimeout 的参数是一个箭头函数，这个箭头函数的定义生效是在 foo 函数生成时
而它的真正执行要等到 100 毫秒后。如果是普通函数，
执行时 this 应该指向全局对象 window ，这时应该输出 21 。
但是，箭头函数导致 this 总是指向函数定义生效时所在的对象（本例是 {id: 42} ）
所以输出的是 42 。
*/
function foo() {
  setTimeout(() => {
    console.log('id:', this.id)
  }, 100)
}
var id = 21
// call会改变函数的this指向
foo.call({ id: 42 }) // id: 42

/*
  Timer 函数内部设置了两个定时器，分别使用了箭头函数和普通函数。
  前者的 this 绑定定义时所在的作用域（即 Timer 函数）
  后者的 this 指向运行时所在的作用域（即全局对象）而全局对象并没有该计时器
  故普通函数中timer.s2 一次也没有更新
*/
function Timer() {
  this.s1 = 0
  this.s2 = 0
  // 箭头函数
  setInterval(() => this.s1++, 1000)
  // 普通函数
  setInterval(function () {
    this.s2++
  }, 1000)
}
var timer = new Timer()
// setTimeout 方法在停止后运行给定的函数。
// 它设置一个计时器，并在时间终止时执行给定的函数（回调）
setTimeout(() => console.log('s1: ', timer.s1), 3100) //s1:3
setTimeout(() => console.log('s2: ', timer.s2), 3100) //s2:0
// 通过handler定义 所以箭头函数里面的 this 总是指向 handler 对象
var handler = {
  id: '123456',
  init: function () {
    document.addEventListener('click', (event) => this.doSomething(event.type), false)
  },
  doSomething: function (type) {
    console.log('Handling ' + type + ' for ' + this.id)
  }
}

// 官方对箭头函数的内部转化解释
// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id)
  }, 100)
}
// 相当于 ES5
function foo() {
  var _this = this//这是解决使用箭头函数常用的this指向问题的方法
  setTimeout(function () {
    console.log('id:', _this.id)
  }, 100)
}
